#include "PlaneHandler.h"
#include "CmdManager.h"
#include "Registry.h"
#include "ActorTable.h"
#include "Scene.h"
#include "SendPointHandlerBase.h"
#include "mainwindow.h"
#include "Operation/OpAdd.h"
#include "Triangles.h"
#include "PointHandler.h"

PlaneHandler::PlaneHandler()
{
}

PlaneHandler::~PlaneHandler()
{
}

void PlaneHandler::input(const QVariant& data, const QString& rawInput, CommandSource cs)
{
	Registry &reg = Registry::instance();
	auto sph = getSendPointHandler();
	Scene* scene = reg.get<Scene>(constructSceneID);
	if (data.type() == QVariant::Bool && !data.toBool())
	{
		if (m_plane)
			scene->removeChild(m_plane);
		emit finished();
		return;
	}

	if (status() == 0)
	{
		if (sph)
		{
			sph->setPointMask(CS_LBTNDOWN);
		}
		emit cmdManager()->setRotatePickNeedShift(true, true);
		m_pointStateMachine = std::make_shared<PointHandler>();
		m_pointStateMachine->setCmdManager(cmdManager());

		m_plane = std::make_shared<Triangles>(scene);
		m_plane->setMode(osg::PrimitiveSet::TRIANGLE_STRIP);
		m_plane->setColor(getCurrentColor());
		scene->addChild(m_plane);
		m_pointStateMachine->setPrompt0(tr("指定起点"));
		m_pointStateMachine->input(data, rawInput, cs);
		setStatus(1);
		return;
	}

	std::vector<osg::Vec3> points = m_plane->getPoints();
	if (status() == 1)
	{
		if (data.type() == QVariant::Bool && data.toBool())
		{
			scene->removeChild(m_plane);
			emit finished();
			return;
		}
		if (sph)
		{
			sph->setPointMask(CS_LBTNDOWN | CS_MOUSEMOVE);
		}
		m_pointStateMachine->input(data, rawInput, cs);
		if (m_pointStateMachine->done())
		{
			osg::Vec3 worldPt = m_pointStateMachine->getPoint();
			points.push_back(worldPt);
			points.push_back(worldPt);
			m_plane->setPoints(points);
			m_pointStateMachine->setPrompt0(tr("指定下一点"));
			m_pointStateMachine->reset();
			setStatus(2);
		}
		return;
	}

	if (status() >= 2)
	{
		if (data.type() == QVariant::Bool && data.toBool())
		{
			if (status() <= 3)
			{
				scene->removeChild(m_plane);
			}
			else
			{
				points.pop_back();
				m_plane->setPoints(points);
			}
			auto undoStack = scene->undoStack();
			std::set<std::shared_ptr<INode>> children;
			children.insert(m_plane);
			undoStack->push(new OpAdd(children));
			emit finished();
			return;
		}

		if (cs == CS_MOUSEMOVE)
		{
			if (data.type() == QVariant::Vector3D)
			{
				auto pt = data.value<QVector3D>();
				osg::Vec3 worldPt = { pt.x(), pt.y(), pt.z() };
				points[points.size() - 1] = worldPt;
			}
			m_plane->setPoints(points);
		}
		else
		{
			m_pointStateMachine->input(data, rawInput, cs);
			if (m_pointStateMachine->done())
			{
				osg::Vec3 worldPt = m_pointStateMachine->getPoint();
				points[points.size() - 1] = worldPt;
				points.push_back(worldPt);
				m_plane->setPoints(points);
				m_pointStateMachine->setPrompt0(tr("指定下一点"));
				setStatus(status() + 1);
				m_pointStateMachine->reset();
			}
		}
		return;
	}

}
